home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / devices / msh_1_5 / part04 < prev    next >
Internet Message Format  |  1990-02-21  |  50KB

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i082: MSH 1.5 - Messydos File System Handler , Part04/06
  5. Message-ID: <11501@xanth.cs.odu.edu>
  6. Date: 21 Feb 90 02:00:50 GMT
  7. Sender: tadguy@cs.odu.edu
  8. Reply-To: Olaf 'Rhialto' Seibert <U211344%HNYKUN11.BITNET@CUNYVM.CUNY.EDU>
  9. Lines: 1338
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: Olaf 'Rhialto' Seibert <U211344%HNYKUN11.BITNET@CUNYVM.CUNY.EDU>
  15. Posting-number: Volume 90, Issue 082
  16. Archive-name: devices/msh-1.5/part04
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 4 (of 6)."
  25. # Contents:  doc/msh.man.uu src/hanfile.c
  26. # Wrapped by tadguy@xanth on Tue Feb 20 20:57:11 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'doc/msh.man.uu' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'doc/msh.man.uu'\"
  30. else
  31. echo shar: Extracting \"'doc/msh.man.uu'\" \(25877 characters\)
  32. sed "s/^X//" >'doc/msh.man.uu' <<'END_OF_FILE'
  33. Xbegin 664 msh.man
  34. XM"B`@("`@35-(.BA&:6QE4WES=&5M<RD@("`@($%M:6=A(%!R;V=R86UM97(GW
  35. XM<R!-86YU86P@("`@("!-4T@Z*$9I;&53>7-T96US*0H*"@H@("`@()LQ;5-9)
  36. XM3D]04UE3(`H@("`@("`@("`@FS!M36]U;G0@35-(.B`*"B`@("`@("`@("!-D
  37. XM4T@Z/&%N>2!V86QI9"!F:6QE('-P96-I9FEC871I;VX^+"!O<B!J=7-T(`H@E
  38. XM("`@("`@("`@/&%N>2`@=F%L:60@9FEL92!S<&5C:69I8V%T:6]N/B!I9B!Y[
  39. XM;W5R(&-U<G)E;G0@9&ER96-T;W)Y(&ES"B`@("`@("`@("!S;VUE=VAE<F4@C
  40. XM;VX@35-(.BX@(`H*("`@("";,6U54T%'12`*("`@("`@("`@()LP;4U32#H@3
  41. XM:7,@82!R96%L($%M:6=A+7-T>6QE($9I;&4@4WES=&5M(&AA;F1L97(@=&AA>
  42. XM="`@:&%N9&QE<PH@("`@("`@("`@;65S<WED;W,@9F]R;6%T=&5D("!D:7-KE
  43. XM971T97,N("`@(%EO=2`@8V%N('5S92!F:6QE<R!O;B!S=6-H"B`@("`@("`@\
  44. XM("!M97-S>61O<R!D:7-K<R!I;B!A;&UO<W0@97AA8W1L>2!T:&4@<V%M92`@=
  45. XM=V%Y("!A<R`@>6]U("!U<V4*("`@("`@("`@(&9I;&5S(&]N(&YO<FUA;"!!S
  46. XM;6EG82!D:7-K<RX@(`H*("`@("`@("`@(%-U<'!O<G1E9"`@87)E("`T,"`@`
  47. XM;W(@(#@P("!T<F%C:W,L("!D;W5B;&4M<VED960@."P@.2!O<B`Q,`H@("`@7
  48. XM("`@("`@<V5C=&]R(&9L;W!P>2!D:7-K<RP@86YD(&AA<F1D:7-K<R!W:71H`
  49. XM(&$@,3(@;W(@(#$V+6)I="`@1D%4"B`@("`@("`@("!O9B!A;GD@("!D:6UEY
  50. XM;G-I;VX@("!T:&4@($9!5"`@86QL;W=S+B`@("`H1'5E("!T;R`@;&%C:R`@G
  51. XM;V8*("`@("`@("`@(&%V86EL86)I;&ET>2P@22!H879E(&YO="!B965N(&%B!
  52. XM;&4@('1O("!T97-T("!-4T@Z("!O;B`@:&%R9`H@("`@("`@("`@9&ES:W,[U
  53. XM('!R;V-E960@=VET:"!E>'1R96UE(&-A=71I;VXI+B`@"@H@("`@()LQ;4U/K
  54. XM54Y43$E35"`*("`@("`@("`@()LP;4$@('-A;7!L92!-;W5N=&QI<W0@96YTN
  55. XM<GDL('1H870@=V]R:W,@=VET:"!T:&4@07)P(#$N,R!-;W5N=`H@("`@("`@-
  56. XM("`@8V]M;6%N9#H@"@H@("`@("`@("`@+RH*("`@("`@("`@("`J("!-97-SR
  57. XM>2!F:6QE('-Y<W1E;2!O;B!M97-S>2!B;&]C:W,Z"B`@("`@("`@("`@*B\*Q
  58. XM("`@("`@("`@($U32#H@("`@1FEL95-Y<W1E;2`]($UE<W-Y1FEL95-Y<W1E-
  59. XM;0H@("`@("`@("`@("`@("`@("!$979I8V4@/2!M97-S>61I<VLN9&5V:6-E^
  60. XM"B`@("`@("`@("`@("`@("`@(%5N:70@/2`Q"B`@("`@("`@("`@("`@("`@"
  61. XM($9L86=S(#T@,`H@("`@("`@("`@+RH*("`@("`@("`@("`J("!(:6=H0WEL9
  62. XM(&ES(&EG;F]R960L($QO=T-Y;"P@4W5R9F%C97,@86YD($)L;V-K<U!E<E1RP
  63. XM86-K"B`@("`@("`@("`@*B`@87)E('5S960@;VYC92!T;R!F:6YD('1H92!BX
  64. XM;V]T8FQO8VLN($9U<G1H97(@<&%R86UE=&5R<PH@("`@("`@("`@("H@(&%R&
  65. XM92!F;W5N9"!T:&5R92X*("`@("`@("`@("`J+PH@("`@("`@("`@("`@("`@4
  66. XM("!,;W=#>6P@/2`P(#L@2&EG:$-Y;"`](#<Y"B`@("`@("`@("`@("`@("`@!
  67. XM(%-U<F9A8V5S(#T@,@H@("`@("`@("`@("`@("`@("!";&]C:W-097)4<F%CD
  68. XM:R`](#D*("`@("`@("`@("`@("`@("`@0G5F9F5R<R`](#4*("`@("`@("`@4
  69. XM("\J"B`@("`@("`@("`@*B`@57-E($)U9DUE;51Y<&4@/2`S(%MF;W(@345-I
  70. XM1E]#2$E0('P@345-1E]054),24-=(&EF('EO=0H@("`@("`@("`@("H@('5S-
  71. XM92!-4T@Z(&]N('1H92!T<F%C:V1I<VLN9&5V:6-E+@H@("`@("`@("`@("HOT
  72. XM"B`@("`@("`@("`@("`@("`@($)U9DUE;51Y<&4@/2`Q"B`@("`@("`@("`@`
  73. XM("`@("`@($)O;W10<FD@/2`P"B`@("`@("`@("`@("`@("`@(%-T86-K<VEZB
  74. XM92`](#0P.38*("`@("`@("`@("`@("`@("`@4')I;W)I='D@/2`U"B`@("`@]
  75. XM("`@("`@("`@("`@($=L;V)696,@(#T@+3$*("`@("`@("`@(",*"B`@("`@>
  76. XM("`@("!4:&ES($UO=6YT;&ES="!E;G1R>2!I;G-T<G5C=',@35-(.B!T;R!UB
  77. XM<V4@(&9L;W!P>2`@=6YI="`@,2P*("`@("`@("`@(&DN92X@($1&,3H@(&%N'
  78. XM9"`@=&AE("!M97-S>61I<VLN9&5V:6-E+B`@(%EO=2!M87D@8VAO;W-E(&%NA
  79. XM>0H@("`@("`@("`@;F%M92!I;G-T96%D(&]F($U32#H@=&AA="!Y;W4@;&EK1
  80. XM92X@("!&;W(@('1H:7,@(&-A<V4L("!-4S$Z"B`@("`@("`@("!W;W5L9"!A;
  81. XM;'-O("!B92!A('-E;G-I8FQE(&-H;VEC92X@(%EO=2!C86X@<F5A9"!T:&4@0
  82. XM<V5P87)A=&4*("`@("`@("`@(&UA;G5A;"!P86=E(&%B;W5T(&UE<W-Y9&ESF
  83. XM:RYD979I8V4N("!)="!I<R`@<W5P<&]S960@('1O("!B90H@("`@("`@("`@7
  84. XM<&]S<VEB;&4@('1O("!U<V4@35-(.B!O;B!A(&AA<F1D:7-K(&)Y('-U<'!L*
  85. XM>6EN9R!T:&4@<')O<&5R"B`@("`@("`@("!D979I8V4@;F%M92!A;F0@=6YI*
  86. XM="!N=6UB97(N("!)9B!Y;W4@=VES:"`@=&\@('5S92`@9FQO<'!I97,*"@H@B
  87. XM("`@($MO<VUO4V]F="`@("`@("`@("`@("`@("`@("`@("`@("TQ+2`@("`@0
  88. XM("`@("`@("`@("`@("`@("!697)S:6]N(#,T+C0*"@H@("`@($U32#HH1FEL2
  89. XM95-Y<W1E;7,I("`@("!!;6EG82!0<F]G<F%M;65R)W,@36%N=6%L("`@("`@9
  90. XM35-(.BA&:6QE4WES=&5M<RD*"@H@("`@("`@("`@=')U;'D@(&-O;7!A=&EB8
  91. XM;&4@('=I=&@@=&AO<V4@;65S<WD@;6%C:&EN97,L('EO=2!S:&]U;&0@=7-E.
  92. XM"B`@("`@("`@("!T:&4@;65S<WED:7-K+F1E=FEC92X@(%EO=2`@8V%N;F]T3
  93. XM("!C:&%N9V4@('1H:7,@(&YA;64@(&EN=&\*("`@("`@("`@('-O;65T:&ENJ
  94. XM9R!E;'-E+B`@"@H@("`@("`@("`@5&AE("!-;W5N=&QI<W0@(&5N=')I97,@\
  95. XM3&]W0WEL+"!3=7)F86-E<RP@86YD($)L;V-K<U!E<E1R86-K"B`@("`@("`@%
  96. XM("!A<F4@=7-E9"!O;F-E('1O(&1E=&5R;6EN92`@=&AE("!L;V-A=&EO;B`@(
  97. XM;V8@('1H92`@;65S<WED;W,*("`@("`@("`@(&)O;W1B;&]C:RX@("!$:7-KO
  98. XM("!B;&]C:W,@(&]F("`U,3(@8GET97,@87)E(&%S<W5M960@:6X@=&AI<PH@5
  99. XM("`@("`@("`@8V%L8W5L871I;VXN("!&=7)T:&5R(&EN9F]R;6%T:6]N(&ES_
  100. XM('1H96X@;V)T86EN960@9G)O;2`@=&AE"B`@("`@("`@("!B;V]T8FQO8VL@S
  101. XM*'-E92!B96QO=RDN("`*"B`@("`@FS%M0T]-4$%424))3$E462`*("`@("`@F
  102. XM("`@()LP;45V96X@('1H;W5G:"`@35-(.B`@=7-E<R`@;VYE(&]F('EO=7(@]
  103. XM9FQO<'!Y(&1R:79E<RP@>6]U(&UA>0H@("`@("`@("`@<W1I;&P@=7-E('1HR
  104. XM870@9')I=F4@9F]R("!N;W)M86P@($%M:6=A("!D:7-K<RX@("`@66]U("!W>
  105. XM:6QL"B`@("`@("`@("!N;W1I8V4@('1H870@('=H96X@('EO=2`@:6YS97)TB
  106. XM("!A(&1I<VL@:6X@=&AE(&1R:79E('5S960@8GD*("`@("`@("`@($U32#HLB
  107. XM(&)O=&@@35-(.B!A;F0@=&AE(')E9W5L87(@06UI9V$@(&9I;&4@('-Y<W1EL
  108. XM;2`@:&%N9&QE<@H@("`@("`@("`@=VEL;"!A='1E;7!T("!T;R!I9&5N=&EF2
  109. XM>2!T:&4@9&ES:RX@(%1H92!R97-U;'0@=VEL;"!B92!T:&%T"B`@("`@("`@-
  110. XM("!O;F4@;V8@=&AE('1W;R!W:6QL(&)E('5N86)L92!T;R!R96%D(&ET+"!A1
  111. XM;F0@=&AE;B!L96%V92`@:70*("`@("`@("`@(&%L;VYE('-O('1H870@=&AEX
  112. XM(&]T:&5R(&UA>2!U<V4@:70N("`*"B`@("`@("`@("!4:&ES("!I<R`@=VAA)
  113. XM="!H87!P96YS('=H96X@>6]U(&EN<V5R="!A(&UE<W-Y9&]S(&1I<VLZ($)OU
  114. XM=&@*("`@("`@("`@(&9I;&4@<WES=&5M<R!W:6QL('1R>2!T;R!R96%D('1H0
  115. XM92!B;V]T(&)L;V-K("!O9B`@=&AE("!D:7-K+@H@("`@("`@("`@5&AE(')EU
  116. XM9W5L87(@06UI9V$@9FEL92!S>7-T96T@9V5T<R!A(')E860@97)R;W(L(&%N4
  117. XM9"!R971R:65S"B`@("`@("`@("!A(&9E=R`@=&EM97,L("!W:&EL92!R96-AQ
  118. XM;&EB<F%T:6YG('1H92!D:7-K(')E860@:&5A9"X@(%1H:7,*("`@("`@("`@&
  119. XM(&ES('1H92!S:&]R="!N;VES92!Y;W4@;6%Y(&AE87(@9G)O;2!T:&4@9')IC
  120. XM=F4N("`@($%T("!A8F]U=`H@("`@("`@("`@=&AE("!S86UE("!T:6UE+"!-2
  121. XM4T@Z('=I;&P@<V5I>F4@8V]N=')O;"!O=F5R('1H92!D:7-K('5N:70L"B`@L
  122. XM("`@("`@("!R96%D('1H92!D:7-K+"!A;F0@<V5E("!T:&%T("!A;&P@(&ESJ
  123. XM("!W96QL+B`@("!)="`@:7,@('1H96X*("`@("`@("`@('!R97!A<F5D('1O*
  124. XM(&%C='5A;&QY('5S92!T:&4@9&ES:RX@(`H*("`@("`@("`@(%1H:7,@(&ES.
  125. XM("!W:&%T(&AA<'!E;G,@=VAE;B!Y;W4@:6YS97)T(&%N($%M:6=A(&1I<VLZZ
  126. XM($%G86EN+`H@("`@("`@("`@8F]T:"!F:6QE('-Y<W1E;7,@=VEL;"!T<GD@2
  127. XM=&\@<F5A9"!T:&4@(&)O;W0@(&)L;V-K("!O9B`@=&AE"B`@("`@("`@("!D#
  128. XM:7-K+B`@0G5T('1H:7,@=&EM92!-4T@Z('=I;&P@9&5S<&5R871E;'D@=')YB
  129. XM('1O('5N9&5R<W1A;F0*("`@("`@("`@('1H92`@9&ES:RP@8G5T(&ET('=IE
  130. XM;&P@9VEV92!U<"!W:&5N(&ET(&ES(&-O;G9I;F-E9"!T:&%T('1H90H@("`@(
  131. XM("`@("`@9&ES:R!I<R!R96%L;'D@;F]T(&UE86YT(&9O<B!I="X@(`H*("`@\
  132. XM("`@("`@($ET(&ES(')E8V]M;65N9&5D('1H870@>6]U(&1O;B=T(&%T=&5M!
  133. XM<'0@=&\@(')E9F5R("!T;R`@35-(.@H@("`@("`@("`@=VAI;&4@;W1H97(@%
  134. XM9FEL97-Y<W1E;7,@87)E('1R>6EN9R!T;R!R96%D('1H92!D:7-K+B`@"@H@:
  135. XM("`@("`@("`@26X@('-O;64@('-I='5A=&EO;G,@('=H97)E('1H97)E(&%RD
  136. XM92!M=6QT:7!L92!E<G)O<G,@870@=&AE"B`@("`@("`@("!S86UE('1I;64@C
  137. XM*'-U8V@@87,@=')Y:6YG('1O(&1E;&5T92!A(&YO;BUE>&ES=&5N="!F:6QEO
  138. XM(&9R;VT*("`@("`@("`@(&$@=W)I=&4M<')O=&5C=&5D(&1I<VLI+"!T:&4@B
  139. XM97)R;W(@<F5P;W)T960@;6%Y(&)E(&1I9F9E<F5N=`H@("`@("`@("`@=&AA;
  140. XM;B!T:&4@<F5G=6QA<B!F:6QE('-Y<W1E;2X@(`H*("`@("";,6U%6%1%3E-)A
  141. XM3TY3(`H@("`@("`@("`@04-424].FS!M7YLQ;41)12`*"B`@("`@("`@("";)
  142. XM,&U4:&4@<&%C:V5T()LS;4%#5$E/3E]$244@FS!M:7,@<W5P<&]R=&5D+"!A'
  143. XM;F0@979E;B!H87,@=&AE("!R97-U;'0*("`@("`@("`@(&]F('-T;W!P:6YGO
  144. XM("!-4T@Z("!A;F0@=6YL;V%D:6YG('1H92!F:6QE('-Y<W1E;2!C;V1E+B`@%
  145. XM5&AI<PH@("`@("`@("`@:7,@8V]N=F5N:65N="!W:&5N('EO=2!D;VXG="!NP
  146. XM965D('1O('5S92!-4T@Z("!F;W(@(&$@('=H:6QE"B`@("`@("`@("!A;F0@^
  147. XM:&5L<',@('EO=2`@=&\@8V]N<V5R=F4@;65M;W)Y+B`@02!P<F]G<F%M(&-A%
  148. XM;&QE9"";,VUD:64@FS!M:7,*("`@("`@("`@('-U<'!L:65D('1H870@<V5N)
  149. XM9',@=&AE($%#5$E/3E]$244@<&%C:V5T('1O(&%N>2!H86YD;&5R('EO=0H@O
  150. XM("`@("`@("`@=VES:"X@($EF('1H97)E(&ES(&%N>2!P<F]G<F%M(')U;FYIX
  151. XM;F<@=&AA="!E>'!E8W1S($U32#H@('1O"B`@("`@("`@("!R96UA:6X@('!R/
  152. XM97-E;G0@979E;B!W:&EL92!T:&5R92!A<F4@;F\@;W!E;B!O<B!L;V-K960@X
  153. XM9FEL97,*("`@("`@("`@(&]N($U32#HL(&ET(&UA>2!B92!D86YG97)O=7,@[
  154. XM=&\@<F5M;W9E($U32#HN("`*"B`@("`@("`@("";,6U!0U1)3TZ;,&U?FS%M<
  155. XM34]214-!0TA%(`H*("`@("`@("`@()LP;4U32#H@(&AA;F1L97,@('1H92`@U
  156. XM<&%C:V5T("";,VU!0U1)3TY?34]214-!0TA%("";,&TH=7-E9"`@8GD@('1H?
  157. XM90H@("`@("`@("`@061D0G5F9F5R<R`@8V]M;6%N9"D@(&%N9"`@8V%C:&4@4
  158. XM8G5F9F5R<R!M;W)E(&EN=&5L;&EG96YT;'DN"@H*("`@("!+;W-M;U-O9G0@5
  159. XM("`@("`@("`@("`@("`@("`@("`@("`M,BT@("`@("`@("`@("`@("`@("`@,
  160. XM("`@5F5R<VEO;B`S-"XT"@H*("`@("!-4T@Z*$9I;&53>7-T96US*2`@("`@X
  161. XM06UI9V$@4')O9W)A;6UE<B=S($UA;G5A;"`@("`@($U32#HH1FEL95-Y<W1E5
  162. XM;7,I"@H*("`@("`@("`@(%=H96X@>6]U(&%D9"!B=69F97)S+"!T:&4@<F5Q!
  163. XM=6ER960@;65M;W)Y(&ES("!N;W0@(&%L;&]C871E9`H@("`@("`@("`@:6UM5
  164. XM961I871E;'DL("!B=70@(&=R861U86QL>2`@87,@=&AE<F4@8F5C;VUE<R!A8
  165. XM('5S92!F;W(@:70N"B`@("`@("`@("!7:&5N('EO=2!R96UO=F4@82!D:7-K2
  166. XM(&ET<R!B=69F97)S(&%R92!N;R!L;VYG97(@;V8@=7-E("!A;F0*("`@("`@8
  167. XM("`@('1H97)E9F]R92!A<F4@(&%L;"`@9G)E960N("!!;F0L('=H870@:7,@X
  168. XM;6]R92!I;7!O<G1A;G0L('EO=0H@("`@("`@("`@8V%N(&1E8W)E87-E('1HN
  169. XM92!M87AI;75M(&YU;6)E<B!O9B!B=69F97)S+B`@0GD@<W!E8VEF>6EN9R!AI
  170. XM"B`@("`@("`@("!N96=A=&EV92!N=6UB97(@>6]U(')E9'5C92!T:&4@;G5ML
  171. XM8F5R(&]F(&)U9F9E<G,N("`@268@('EO=7(*("`@("`@("`@($%D9$)U9F9E"
  172. XM<G,@(&1O97,@;F]T(&QI:V4@;F5G871I=F4@8G5F9F5R(&-O=6YT<RP@<VEMD
  173. XM<&QY(&%D9`H@("`@("`@("`@-C4U,S8@=&\@=&AE("AN96=A=&EV92D@;G5M)
  174. XM8F5R('EO=2`@86-T=6%L;'D@(&EN=&5N9"X@("`@4V\L"B`@("`@("`@("!IF
  175. XM;G-T96%D("!O9B`@+3$@>6]U(&-A;B!A;'-O('-P96-I9GD@-C4U,S4L("TRV
  176. XM(&ES(#8U-3,T+B!9;W4*("`@("`@("`@('=O=6QD;B=T('=A;G0@('1O("!A*
  177. XM9&0@(&UO<F4@('1H86X@(#,R-S8W("!B=69F97)S("!A="`@;VYC90H@("`@@
  178. XM("`@("`@86YY=V%Y+B`@"@H@("`@()LQ;4Q)34E4051)3TY3(`H@("`@("`@+
  179. XM("`@FS!M1'5E("!T;R`@=&AE("!D:69F97)E;F-E("!B971W965N(&UE<W-Y@
  180. XM9&]S(&%N9"!!;6EG841/4R!F:6QE"B`@("`@("`@("!S>7-T96US+"!N;W0@=
  181. XM86QL(&]P97)A=&EO;G,@=&AA="`@87)E("!A=F%I;&%B;&4@(&9O<B`@06UIE
  182. XM9V$*("`@("`@("`@(&9I;&5S(&-A;B!B92!A<'!L:65D('1O(&UE<W-Y9&]SW
  183. XM(&9I;&5S+B`@"@H@("`@("`@("`@FS%M1FEL92!N86UE<R`*"B`@("`@("`@6
  184. XM("";,&U4:&4@("!M;W-T("!E>64M8V%T8VAI;F<@(&1I9F9E<F5N8V4@(&%R+
  185. XM92`@=&AE("!F:6QE("!N86UE<SH*("`@("`@("`@(&UE<W-Y9&]S(&9I;&4@U
  186. XM;F%M97,@8V%N(&)E(&%T(&UO<W0@(C@@*R`S(B!C:&%R86-T97)S("!L;VYG/
  187. XM+@H@("`@("`@("`@5&AI<R`@;65A;G,@('1H870@('1H92`@(F)A<V4B("!PE
  188. XM87)T(&]F('1H92!F:6QE(&YA;64@;6%Y(&)E"B`@("`@("`@("!E:6=H="!C*
  189. XM:&%R86-T97)S(&QO;F<L(&UA>6)E(&9O;&QO=V5D(&)Y("!A("!T:')E92UCG
  190. XM:&%R86-T97(*("`@("`@("`@(")E>'1E;G-I;VXB+"`@=VAI8V@@(&ES("!S#
  191. XM97!A<F%T960@9G)O;2!T:&4@8F%S92!N86UE('=I=&@@80H@("`@("`@("`@>
  192. XM<&5R:6]D("@G+B<I+B!!;'-O+"!Y;W4@8V%N;F]T('5S92`@86QL("!C:&%R=
  193. XM86-T97)S("!I;B`@=&AE"B`@("`@("`@("!F:6QE("!N86UE<R`@>6]U("!WL
  194. XM:7-H+"!B=70@=&AE(&-H87)A=&5R(&-H;VEC92!I<R!B87-I8V%L;'D*("`@K
  195. XM("`@("`@(&QI;6ET960@=&\@=&AE('5P<&5R8V%S92!L971T97)S($$M6BP@K
  196. XM9&EG:71S(#`M.2P@(&%N9"`@;6]S=`H@("`@("`@("`@(G!U;F-T=6%T:6]N"
  197. XM(B!C:&%R86-T97)S("!E>&-E<'0@('-P86-E("H@/R`@+B`\(#X@+R`]('P@P
  198. XM+"`Z"B`@("`@("`@("!A;F0@7"X@(`H*("`@("`@("`@($U32#H@=VEL;"!T/
  199. XM<GD@=&\@;6%P("!F:6QE("!N86UE<R`@=&AA="`@>6]U("!O<B`@82`@<')OA
  200. XM9W)A;0H@("`@("`@("`@871T96UP=',@=&\@=7-E('1O(&YA;65S('1H870@[
  201. XM87)E(&%C='5A;&QY(&%L;&]W960N("!"=70@9F]R"B`@("`@("`@("!U=&UO.
  202. XM<W0@(&9L97AI8FEL:71Y+"`@;VYL>2`@=&AE("!M;W-T("!B87-I8R!L:6UI+
  203. XM=&%T:6]N<R!A<F4*("`@("`@("`@(&5N9F]R8V5D.B`@=&AE("!L96YG=&@@'
  204. XM(&]F("`@=&AE("`@;F%M92`@("@X*S,I+"`@('5P<&5R8V%S90H@("`@("`@<
  205. XM("`@86QP:&%B971I8W,L("!A;F0@('1H92`@<')E<V5N8V4@(&]F("!O;FQYL
  206. XM(&]N92!P97)I;V0@:6X@=&AE"B`@("`@("`@("!N86UE+B`@5&AI<R!M96%N/
  207. XM<R!T:&%T('EO=2!M:6=H="!C<F5A=&4@9FEL92`@;F%M97,@('1H870@(&$*^
  208. XM("`@("`@("`@(&UE<W-Y9&]S("!C;VUP=71E<B`@9&]E<R`@;F]T("!C;W)R8
  209. XM96-T;'D@:VYO=R!H;W<@=&\@:&%N9&QE+@H@("`@("`@("`@0G5T(&-A<F4@[
  210. XM:&%S(&)E96X@=&%K96X@=&AA="!I;B!N;R!C87-E(&ET('=O=6QD(&)E('!O8
  211. XM<W-I8FQE"B`@("`@("`@("!T;R!C<F5A=&4@82!F:6QE(&YA;64@=&AA="P@B
  212. XM;VYC92!C<F5A=&5D+"!C86YN;W0@8F4@(&AA;F1L960*("`@("`@("`@(&%N\
  213. XM>6UO<F4@(&)Y($U32#HN(%EO=2!C86X@86QW87ES(')E9F5R('1O('1H870@_
  214. XM9FEL92!W:71H('1H90H@("`@("`@("`@<V%M92!N86UE('EO=2!U<V5D(&)E#
  215. XM9F]R92P@979E;B!I9B!-4T@Z(&-H86YG960@:70@9F]R('EO=2X@(`H*("`@$
  216. XM("`@("`@()LQ;5-P96-I86P@9&ER96-T;W)I97,@FS!M+B";,6UA;F0@FS!M!
  217. XM+BX@"@H@("`@("`@("`@3VX@;65S<WED;W,@9FQO<'!I97,L(&5V97)Y("!S0
  218. XM=6)D:7)E8W1O<GD@(&AA<R`@='=O("!S<&5C:6%L"B`@("`@("`@("!E;G1RF
  219. XM:65S(&-A;&QE9"`@(BXB("`@(&%N9"`B+BXB+B!4:&5Y(')E9F5R('1O('1H&
  220. XM92!D:7)E8W1O<GD*("`@("`@("`@(&ET<V5L9B!A;F0@:71S(")P87)E;G0B<
  221. XM(&1I<F5C=&]R>2P@<F5S<&5C=&EV96QY+B`@("!0<F]G<F%M<PH@("`@("`@#
  222. XM("`@=&AA="`@=')A=F5R<V4@9&ER96-T;W)Y('1R965S(&]N(&UE<W-Y9&]S)
  223. XM('-Y<W1E;7,@=&%K92!C87)E"B`@("`@("`@("!T;R!S:VEP('1H97-E(")SJ
  224. XM=6)D:7)E8W1O<FEE<R(L('-I;F-E('1H97D@(')E86QL>2`@87)E("!N;W0*J
  225. XM("`@("`@("`@(")S=6(B(&1I<F5C;W)I97,@86YD(')E8W5R<VEV96QY(&5NZ
  226. XM=&5R:6YG('1H96T@=V]U;&0@;&5A9"!T;PH@("`@("`@("`@;F]T:&EN9R!B>
  227. XM=70@('1R;W5B;&4N("`@("A4:&5I<B`@<')E<V5N8V4@('!R979E;G1S('1H`
  228. XM92!F:6QE"B`@("`@("`@("!S>7-T96T@9G)O;2!H879E(&$@=')E92!S=')UK
  229. XM8W1U<F4N*2!"=70@('=I=&@@($%M:6=A1$]3("`Q+C,*("`@("`@("`@(&%NQ
  230. XM9"`@8F5F;W)E+"`@;F\@('-U8V@@(")H87)D("!L:6YK<R(@(&5X:7-T+"`@P
  231. XM86YD(&1I<F5C=&]R>0H@("`@("`@("`@=')A=F5R<VEN9R`@<')O9W)A;7,@"
  232. XM('=O=6QD("!N;W0@(&AE<VET871E("!T;R`@96YT97(@('1H96TN"B`@("`@Z
  233. XM("`@("!4:&5R969O<F4L('1H97D@(&%R92`@FS-M8V]M<&QE=&5L>2`@FS!MS
  234. XM:&ED9&5N("!F<F]M("!S:6=H="X@("!9;W4*("`@("`@("`@(&-A;FYO="!SJ
  235. XM964@=&AE;2!I;B!D:7)E8W1O<GD@;&ES=&EN9W,@;F]R(')E9F5R('1O("!TK
  236. XM:&5M("!B>0H@("`@("`@("`@86YY(&YA;64N("`*"@H*("`@("!+;W-M;U-OI
  237. XM9G0@("`@("`@("`@("`@("`@("`@("`@("`M,RT@("`@("`@("`@("`@("`@G
  238. XM("`@("`@5F5R<VEO;B`S-"XT"@H*("`@("!-4T@Z*$9I;&53>7-T96US*2`@X
  239. XM("`@06UI9V$@4')O9W)A;6UE<B=S($UA;G5A;"`@("`@($U32#HH1FEL95-YI
  240. XM<W1E;7,I"@H*("`@("`@("`@($)U="`@979E;B`@=VAI;&4@(&ET("!I<R!HF
  241. XM:61D96XL('1H92`B+BXB(&5N=')Y(&ES(&]F(&-O=7)S90H@("`@("`@("`@/
  242. XM<W1I;&P@=7!D871E9"!T;R!R969L96-T('1H92!N97<@('!A<F5N="`@9&ER+
  243. XM96-T;W)Y("!W:&5N("!A"B`@("`@("`@("!D:7)E8W1O<GD@:7,@(')E;F%M7
  244. XM960@(&%N9"`@;6]V960N("`@($YO=&4L(&)Y('1H92!W87DL('1H870*("`@[
  245. XM("`@("`@(&UO=FEN9R!D:7)E8W1O<FEE<R!I<R!A;B!O<&5R871I;VX@=&AAF
  246. XM="!I<R!N;W0@<W5P<&]R=&5D("!B>0H@("`@("`@("`@;65S<WED;W,@:71SS
  247. XM96QF+B`@"@H@("`@("`@("`@3V8@(&-O=7)S92P@('1H92`@=7-U86P@(&UEH
  248. XM=&AO9',@(&]F("!A8V-E<W-I;F<@('1H92!C=7)R96YT"B`@("`@("`@("!DY
  249. XM:7)E8W1O<GD@*'1H92!E;7!T>2!N86UE("(B*2!A;F0@=&AE('!A<F5N="!DY
  250. XM:7)E8W1O<GD@*"(O(BD*("`@("`@("`@(&1O('=O<FLN("`*"B`@("`@("`@7
  251. XM("!)="!M87D@8F4@('1H870@(&EN("!T:&4@(&9U='5R92P@('=H96X@('-OO
  252. XM9G1L:6YK<R`@=VEL;"`@8F4*("`@("`@("`@(&EN8VQU9&5D(&EN($%M:6=A"
  253. XM1$]3+"!T:&5S92`B+B(@86YD("(N+B(@9&ER96-T;W)I97,@=VEL;"!B90H@6
  254. XM("`@("`@("`@;6%D92!V:7-I8FQE("!A9V%I;BP@8G5T(&EN('1H92!D:7-G[
  255. XM=6ES92!O9B!A('-O9G0@;&EN:RX@($EN"B`@("`@("`@("!T:&%T(&-A<V4L>
  256. XM('!R;V=R86US('=H:6-H(&1O;B=T("!K;F]W("!H;W<@('1O("!H86YD;&4@V
  257. XM('1H96T*("`@("`@("`@('-H;W5L9"`@(&5I=&AE<B`@;F]T("!E>&ES="`@&
  258. XM86YY;6]R92`@;W(@(&EG;F]R92`@=&AE("!L:6YK<PH@("`@("`@("`@=&AE-
  259. XM;7-E;'9E<RX@(`H*("`@("`@("`@()LQ;49I;&5N;W1E<R`*"B`@("`@("`@7
  260. XM("";,&U-97-S>61O<R!H87,@;F\@<')O=FES:6]N(&9O<B!F:6QE(&YO=&5SA
  261. XM(&%N9"!T:&5R969O<F4@('1H97D*("`@("`@("`@(&-A;FYO="!B92!S=7!P-
  262. XM;W)T960N("`*"B`@("`@("`@("";,6U&:6QE('!R;W1E8W1I;VX@8FET<R!VH
  263. XM<YLP;2X@()LQ;69I;&4@871T<FEB=71E<R`*"B`@("`@("`@("";,&U#=7)RA
  264. XM96YT;'DL("!T:&4@(&9O;&QO=VEN9R`@:6YT97)P<F5T871I;VX@(&]F(&UEI
  265. XM<W-Y9&]S(&9I;&4*("`@("`@("`@(&%T=')I8G5T97,@:7,@<&5R9F]R;65D6
  266. XM+B`@("!4:&4@($1I<F5C=&]R>2`@86YD("!6;VQU;65L86)E;`H@("`@("`@9
  267. XM("`@871T<FEB=71E<R`@87)E("!H;VYO<F5D("!T;R`@;6%K92`@=&AE<V4@(
  268. XM(&1I<F5C=&]R>2!E;G1R:65S"B`@("`@("`@("!D:69F97)E;G0@9G)O;2!PT
  269. XM;&%I;B!F:6QE<RX@(`H@("`@("`@("`@5&AE($A)1$1%3B!A;F0@4UE35$5-4
  270. XM(&%T=')I8G5T97,@87)E(&UA<'!E9"!T;R!T:&4@($@H:61D96XI"B`@("`@!
  271. XM("`@("!B:70N("`@5&AE("!(("!B:70@(&ES("!M87!P960@('1O('1H92!(4
  272. XM241$14X@871T<FEB=71E.R!T:&4*("`@("`@("`@(%-94U1%32!A='1R:6)U^
  273. XM=&4@8V%N;F]T(&)E(&-H86YG960N("`*("`@("`@("`@(%1H92`@4D5!1"U/^
  274. XM3DQ9("!A='1R:6)U=&4@(&ES("!M87!P960@('1O("!T:&4@(%<H<FET92D@Z
  275. XM(&%N9`H@("`@("`@("`@1"AE;&5T92D@8FET<RX@("!);G9E<G-E;'DL(&EF]
  276. XM(&$@9FEL92!I<R!S970@=&\@96ET:&5R(%=R:71E"B`@("`@("`@("!O<B!$'
  277. XM96QE=&4@<')O=&5C=&5D+"!T:&4@4D5!1"U/3DQ9(&%T=')I8G5T92!I<R!ST
  278. XM970N("`*("`@("`@("`@(%1H92!!4D-(259%(&)I="P@=VAE;B!C;&5A<BP@D
  279. XM<V5T<R!T:&4@02AR8VAI=F5D*2`@8FET+B`@("!/;@H@("`@("`@("`@;65SP
  280. XM<WED;W,@('1H92`@05)#2$E612`@871T<FEB=71E("!M96%N<R`H=VAE;B!SJ
  281. XM970I('1H870@=&AE"B`@("`@("`@("!F:6QE($U54U0@8F4@8F%C:V5D('5PM
  282. XM("AB>2!A(&)A8VMU<"!P<F]G<F%M*2X@($$@=W)I=&4@=&\@(&$*("`@("`@C
  283. XM("`@(&9I;&4@<V5T<R`@=&AE("!!4D-(259%(&%T=')I8G5T92X@($]N($%MO
  284. XM:6=A1$]3('1H92!!<F-H:79E9`H@("`@("`@("`@8FET(&UE86YS("`H=VAEG
  285. XM;B`@<V5T*2`@=&AA="`@=&AE("!F:6QE("!H87,@(&)E96X@(&%R8VAI=F5D1
  286. XM"B`@("`@("`@("!A;')E861Y+B`@($$@('=R:71E('1O(&$@9FEL92!C;&5A?
  287. XM<G,@=&AE($%R8VAI=F5D('!R;W1E8W1I;VX*("`@("`@("`@(&)I="X@(`H*^
  288. XM("`@("`@("`@()LQ;4)O;W0@8FQO8VL@9F]R;6%T(`H*("`@("`@("`@()LP@
  289. XM;4U32#H@<F5L:65S(&]N('1H92!I;F9O<FUA=&EO;B!I;B!T:&4@8F]O="`@#
  290. XM8FQO8VL@(')E9V%R9&EN9PH@("`@("`@("`@=&AE("!N=6UB97(@;V8@8GETV
  291. XM97,@<&5R(&)L;V-K+"!B;&]C:W,@<&5R('1R86-K+"!T<F%C:W,@<&5R"B`@5
  292. XM("`@("`@("!C>6QI;F1E<BP@8FQO8VMS('!E<B!C;'5S=&5R+"!E=&,N("!4W
  293. XM:&4@<&AY<VEC86P@:6YF;W)M871I;VX*("`@("`@("`@(&ES(&YO="!A8W1UT
  294. XM86QL>2!U<V5D('1O(&%C8V5S<R`@=&AE("!D:7-K+"`@97AC97!T("!F;W(@@
  295. XM('1H90H@("`@("`@("`@;G5M8F5R("!O9B`@=')A8VMS("!W:&EC:"!I<R!DD
  296. XM97)I=F5D(&9R;VT@;W1H97(@:6YF;W)M871I;VXN"B`@("`@("`@("!)="!I9
  297. XM<R!U<V5D('1O(&1E8VED92!I9B!A(#0P('1R86-K(&1I<VL@:7,@:6YS97)TJ
  298. XM960@:6X@82`@.#`*("`@("`@("`@('1R86-K(&1R:79E+B`@(%-I;F=L92`@R
  299. XM<VED960@(&1I<VMS("!A<F4@;F]T('-U<'!O<G1E9"X@(%1H90H@("`@("`@/
  300. XM("`@;G5M8F5R(&]F('-E8W1O<G,@;6%Y("!B92`@=VAA=&5V97(@('1H92`@6
  301. XM=6YD97)L>6EN9R`@9&5V:6-E"B`@("`@("`@("!D<FEV97(@<W5P<&]R=',NE
  302. XM("`H5VET:"!M97-S>61I<VLN9&5V:6-E('1H:7,@:7,@."P@.2!O<B`Q,#L*6
  303. XM("`@("`@("`@('=I=&@@('1R86-K9&ES:RYD979I8V4@(&ET("!I<R`@,3$I>
  304. XM+B!/;FQY('1H92!L;V=I8V%L(&QA>6]U=`H@("`@("`@("`@:6YF;W)M871I=
  305. XM;VX@:7,@=7-E9#H@4VEZ92!O9B!A("!B;&]C:RP@(&YU;6)E<B`@;V8@(')E!
  306. XM<V5R=F5D"B`@("`@("`@("!B;&]C:W,L("!N=6UB97(@;V8@1D%4<RP@;G5M%
  307. XM8F5R(&]F(&)L;V-K<R!P97(@1D%4+"!N=6UB97(@;V8*("`@("`@("`@(')OC
  308. XM;W0@9&ER96-T;W)Y(&5N=')I97,L(&YU;6)E<B!O9B!B;&]C:W,@<&5R(&-LP
  309. XM=7-T97(N("`@(%1H90H@("`@("`@("`@=&]T86P@(&YU;6)E<B!O9B!B;&]CN
  310. XM:W,@:7,@=7-E9"!T;R!D971E<FUI;F4@=&AE('5S86)L92!P87)T"@H*("`@=
  311. XM("!+;W-M;U-O9G0@("`@("`@("`@("`@("`@("`@("`@("`M-"T@("`@("`@3
  312. XM("`@("`@("`@("`@("`@5F5R<VEO;B`S-"XT"@H*("`@("!-4T@Z*$9I;&53*
  313. XM>7-T96US*2`@("`@06UI9V$@4')O9W)A;6UE<B=S($UA;G5A;"`@("`@($U3!
  314. XM2#HH1FEL95-Y<W1E;7,I"@H*("`@("`@("`@(&]F('1H92!D:7-K+B`@0G5T#
  315. XM(&EF('1H92!&050@<V%Y<R`B=7-E(&$@(&)L;V-K("!B97EO;F0@('1H90H@R
  316. XM("`@("`@("`@;&EM:70B+"!T:&ES(&5R<F]R(&ES(&YO="!D971E8W1E9"X@,
  317. XM(`H*("`@("`@("`@($EF("!Y;W4@9F]R;6%T(&$@9&ES:R!O;B!A(&UE<W-Y$
  318. XM9&]S(&-O;7!U=&5R(&%N9"!W:7-H('1O('5S90H@("`@("`@("`@:70@=VET.
  319. XM:"!-4T@Z+"!B92!S=7)E('1O('5S92!A(&UE<W-Y9&]S('9E<G-I;VX@(&YE=
  320. XM=R`@96YO=6=H"B`@("`@("`@("!T;R!W<FET92`@=&AI<R`@:6YF;W)M871IV
  321. XM;VX@:6X@=&AE(&)O;W0@8FQO8VLN("`H5F5R<VEO;B`S+C(*("`@("`@("`@-
  322. XM('=O<FMS(&YI8V5L>2!F;W(@;64N*2!)9B!Y;W4@=VES:"!T;R!F;W)M870@=
  323. XM<W5C:"!A("!D:7-K("!O;@H@("`@("`@("`@>6]U<B`@06UI9V$L("!Y;W4@=
  324. XM(&-A;B`@=7-E("!00T8W,C`@(&)Y("!797)N97(@1_QN=&AE<B!W:71H"B`@)
  325. XM("`@("`@("!P8T9O<FUA="!O;B!T:&4@17AT<F%S(&1I<VLL(&]R('5S92`@6
  326. XM=&AE("!S=7!P;&EE9"`@;65S<WEF;70*("`@("`@("`@('!R;V=R86TN("`*9
  327. XM"B`@("`@("`@("";,6U&050@"@H@("`@("`@("`@FS!M5&AE("`@1D%4("`@&
  328. XM:7,@(&-U<G)E;G1L>2`@;F]T("!C:&5C:V5D("!F;W(@(&EN=&5G<FET>2`@"
  329. XM86YD"B`@("`@("`@("!C;VYS:7-T96YC>2X@(%1H92!&050@:7,@87-S=6UEC
  330. XM9"!T;R!H879E(#$R+6)I="`@96YT<FEE<R`@:68*("`@("`@("`@('1H92!DR
  331. XM:7-K("!H87,@870@;6]S="`T,#@V("@D1D8V*2!C;'5S=&5R<RX@($EF('1H2
  332. XM92!D:7-K(&AA<PH@("`@("`@("`@;6]R92!C;'5S=&5R<R!T:&%N('1H870LF
  333. XM(#$V(&)I="`@1D%4("!E;G1R:65S("!A<F4@(&%S<W5M960N"B`@("`@("`@=
  334. XM("!4:&ES(&ES('1H92!M971H;V0@=&AA="!S965M<R!T;R!B92!U<V5D(&)Y:
  335. XM(&UE<W-Y(&1O<R`S+C`N("`*"B`@("`@("`@("";,6U7;W)K8F5N8V@@"@H@:
  336. XM("`@("`@("`@FS!M5&AE("!7;W)K8F5N8V@@=V%N=',@=&\@=7-E(&9I;&5N'
  337. XM86UE<R!T:&%T(&%R92!I;7!O<W-I8FQE(&]N"B`@("`@("`@("!M97-S>61OQ
  338. XM<R!F;&]P<&EE<RX@("@N:6YF;R!E>'1E;G-I;VXI($ET("!I<R`@=&AE<F5F"
  339. XM;W)E("!N;W0*("`@("`@("`@('9E<GD@969F96-T:79E('1O('1R>2!T;R!U2
  340. XM<V4@5V]R:V)E;F-H(&]N($U32#HN("`*"B`@("`@("`@("";,6U6;VQU;64@M
  341. XM;&%B96P@"@H@("`@("`@("`@FS!M3F]R;6%L("!!;6EG841/4R`@9FQO<'!ID
  342. XM97,@(&AA=F4@82!P87)T(&]F('1H92!D:7-K(')E<V5R=F5D"B`@("`@("`@_
  343. XM("!F;W(@=&AE:7(@;F%M92X@(%=I=&@@;65S<WED;W,@9FQO<'!I97,@82!NV
  344. XM86UE(&ES("!O<'1I;VYA;"P*("`@("`@("`@(&%N9"`@<VAO=6QD(&)E(&ENK
  345. XM('1H92!D:7)E8W1O<GD@:6X@86X@96YT<GD@=VET:"!T:&4@<W!E8VEA;`H@V
  346. XM("`@("`@("`@9FQA9R`@*&%T=')I8G5T92D@(%9O;'5M96QA8F5L+B`@35-(M
  347. XM.B`@;&]O:W,@(&EN("!T:&4@(&9I<G-T"B`@("`@("`@("!D:7)E8W1O<GD@A
  348. XM8FQO8VL@(&]N;'D@('1O("!L;V-A=&4@('-U8V@@(&$@=F]L=6UE(&QA8F5L4
  349. XM+B`@268*("`@("`@("`@(&9O=6YD+"!I="!D96-I9&5S('1H92!N86UE(&]FT
  350. XM('1H92!D:7-K.R!I9B`@;F]T("!F;W5N9"P@('1H90H@("`@("`@("`@;F%MV
  351. XM92!W:6QL(&)E8V]M92`B56YN86UE9"(@86YD('1H92!C<F5A=&EO;B!D871E;
  352. XM('=I;&P@8F5C;VUE"B`@("`@("`@("`Q+4IA;BTX,"X@($YO=&4@=&AA="!!O
  353. XM;6EG841/4R`H86YD($U32#HI(&ME97`@9&ES:W,@87!A<G0@8GD*("`@("`@J
  354. XM("`@('1H96ER(&YA;64@86YD(&-R96%T:6]N(&1A=&4N("!!<R!A("!R97-U%
  355. XM;'0L("!A;&P@('5N;&%B96QE9`H@("`@("`@("`@9&ES:W,@=VEL;"!L;V]K&
  356. XM('1H92!S86UE(&%N9"!C86YN;W0@8F4@9&ES=&EN9W5I<VAE9"X@($ET(&ES_
  357. XM"B`@("`@("`@("!T:&5R969O<F4@('-T<F]N9VQY("!R96-O;6UE;F1E9"!TG
  358. XM:&%T('EO=2!P<F]V:61E(&5V97)Y(&1I<VL*("`@("`@("`@('=I=&@@82!U%
  359. XM;FEQ=64@=F]L=6UE(&QA8F5L.R!T:&4@('-T86YD87)D("!!;6EG841/4R`@L
  360. XM8V]M;6%N9`H@("`@("`@("`@4F5L86)E;"!C86X@(&)E('5S960@9F]R('1HM
  361. XM:7,N("!)9B!Y;W4@;&%B96P@82!D:7-K('1H870@:&%D"B`@("`@("`@("!NX
  362. XM;R!L86)E;"`H:6X@=&AE(&9I<G-T(&1I<F5C=&]R>2!S96-T;W(I(&)E9F]R3
  363. XM92P@($U32#H@('=I;&P*("`@("`@("`@('1R>2`@=&\@(&UO=F4@(&$@(&9I>
  364. XM;&4@(&9R;VT@('1H92`@9FER<W0@(&1I<F5C=&]R>2!B;&]C:R!T;PH@("`@[
  365. XM("`@("`@<V]M97=H97)E(&5L<V4@:6X@=&AE("!R;V]T("!D:7)E8W1O<GDNW
  366. XM("`@($EF("!T:&ES("!I<R`@;F]T"B`@("`@("`@("!P;W-S:6)L92P@(&9O`
  367. XM<B`@:6YS=&%N8V4@8F5C875S92!T:&4@<F]O="!D:7)E8W1O<GD@:7,@9G5L<
  368. XM;"P*("`@("`@("`@('1H96X@=&AE(&QA8F5L:6YG('=I;&P@9F%I;"!A<R!WO
  369. XM96QL+B`@"@H@("`@("`@("`@FS%M375L=&EP;&4@9FEL92!S>7-T96US(`H*P
  370. XM("`@("`@("`@()LP;51H92!-97-S>49I;&53>7-T96T@(&ES("!U;F9O<G1U^
  371. XM;F%T96QY("!N;W0@(&!@<'5R92<G+B`@5&AI<PH@("`@("`@("`@;65A;G,@L
  372. XM=&AA="!I9B!Y;W4@=VES:"!T;R!M;W5N="!M=6QT:7!L92!M97-S>2!F:6QEK
  373. XM('-Y<W1E;7,L"B`@("`@("`@("!Y;W4@(&UU<W0@(&UA:V4@82!C;W!Y(&]F#
  374. XM($UE<W-Y1FEL95-Y<W1E;2!F;W(@96%C:"!O9B!T:&5S92P*("`@("`@("`@2
  375. XM(&%N9"!M;W5N="!E86-H(&]N92!F<F]M(&]N92!O9B!T:&4@<V5P87)A=&4@:
  376. XM8V]P:65S+B`@4G5N;FEN9PH@("`@("`@("`@='=O(&9I;&4@<WES=&5M<R!FT
  377. XM<F]M('1H92!S86UE(&1I<VL@9FEL92`@=VEL;"`@8V%U<V4@(&=R96%T"B`@F
  378. XM("`@("`@("!T<F]U8FQE<RX@("`H3V@@('=E;&PL(&UA>6)E($%M:6=A1$]30
  379. XM(&ES(&YO="!S;R!S;6%R="!T;R!S964*("`@("`@("`@('1H870@='=O(&9IZ
  380. XM;&4@<WES=&5M<R!S:&%R92!T:&4@<V%M92!&:6QE4WES=&5M(&YA;64@:6X@@
  381. XM('1H90H@("`@("`@("`@36]U;G1L:7-T+"`@<V\@(&UA>6)E('EO=2!D;VXG;
  382. XM="!N965D('1O(&AA=F4@;75L=&EP;&4@8V]P:65S"B`@("`@("`@("!O9B!-R
  383. XM97-S>49I;&53>7-T96T@;VX@>6]U<B!D:7-K+B`@5')Y(&%T('EO=7(@;W=N%
  384. XM(')I<VLN*2`*"@H*("`@("!+;W-M;U-O9G0@("`@("`@("`@("`@("`@("`@=
  385. XM("`@("`M-2T@("`@("`@("`@("`@("`@("`@("`@5F5R<VEO;B`S-"XT"@H*<
  386. XM("`@("!-4T@Z*$9I;&53>7-T96US*2`@("`@06UI9V$@4')O9W)A;6UE<B=S@
  387. XM($UA;G5A;"`@("`@($U32#HH1FEL95-Y<W1E;7,I"@H*("`@("";,6U55$E,>
  388. XM251)15,@"B`@("`@("`@("";,&U!('!R;V=R86T@8V%L;&5D()LS;6UE<W-Y*
  389. XM9FUT()LP;6%L;&]W<R`@>6]U("!T;R`@9F]R;6%T("!D:7-K<R`@:6X*("`@9
  390. XM("`@("`@(&UE<W-Y9&]S(&9O<FUA="X@(`H*("`@("`@("`@(%5S86=E.B!->
  391. XM97-S>69M="`\=6YI=&YR/B`\9&5V:6-E/B`*"B`@("`@("`@("!4:&4@("`@D
  392. XM/&1E=FEC93X@("!N86UE("`@:7,@("!O<'1I;VYA;"`@(&%N9"`@(&1E9F%UE
  393. XM;'1S("`@=&\*("`@("`@("`@(")M97-S>61I<VLN9&5V:6-E(BX@5&AE('!R/
  394. XM;V=R86T@87-K<R!F;W(@86QL("!P87)A;65T97)S("!T;PH@("`@("`@("`@)
  395. XM<'5T(&EN('1H92!B;V]T8FQO8VLL(&QI:V4@"@H@("`@("`@("`@0GET97,@<
  396. XM<&5R('-E8W1O<C\@(%LU,3)=(`H*("`@("`@("`@($EF("!Y;W4@(&IU<W0@L
  397. XM(&AI="`@<F5T=7)N("!Y;W4@(&%C8V5P="`@=&AE("!D969A=6QT('9A;'5EU
  398. XM+`H@("`@("`@("`@;W1H97)W:7-E('EO=2!C86X@96YT97(@82!N97<@=F%LK
  399. XM=64@:6X@=&AE("!U<W5A;"`@;F]T871I;VXZ"B`@("`@("`@("`P>"`@/2`@Q
  400. XM:&5X861E8VEM86PL("`P("`]("!O8W1A;"P@(&%N9"`@979E<GET:&EN9R`@%
  401. XM96QS92`@:7,*("`@("`@("`@(&1E8VEM86PN("!!("!F97<@('-U9F9I>&5S\
  402. XM("!A<F4@(&%L;&]W960@(&%S("!M=6QT:7!L:6-A=&EO;@H@("`@("`@("`@L
  403. XM9F%C=&]R.B`@;2`@/2`@;65G82`@*#$P-#@U-S8I+"!K(#T@:VEL;R`H,3`R[
  404. XM-"DL(',@/2!S96-T;W)S"B`@("`@("`@("`H-3$R*2!A;F0@8B`](&)Y=&4@U
  405. XM*#$I+B`H3F]T(&%L;"!T97)M<R!M86ME('-E;G-E("!W:71H("!A;&P*("`@H
  406. XM("`@("`@('%U97-T:6]N<RXI("!9;W4@(&UA>2`@8W)E871E("`X+"`@.2`@W
  407. XM;W(@(#$P('-E8W1O<B!D:7-K<R!B>0H@("`@("`@("`@86YS=V5R:6YG('1H_
  408. XM92!Q=65S=&EO;B`B4V5C=&]R<R!P97(@=')A8VLB(&%P<')O<')I871E;'DNZ
  409. XM("`*("`@("`@("`@(%EO=2!A<F4@86QS;R!A<VME9"!I9B!Y;W4@=VES:"!TQ
  410. XM;R!F;W)M870@=&AE('=H;VQE("!D:7-K("!O<@H@("`@("`@("`@;VYL>2`@0
  411. XM=&AE("!F:7)S="!P87)T('=I=&@@=&AE(&)O;W1B;&]C:RP@1D%4(&%N9"!D:
  412. XM:7)E8W1O<GDN"B`@("`@("`@("!&:6YA;&QY+"!T;R!S964@:68@>6]U(&%RC
  413. XM92!S=&EL;"!A=V%K92P@>6]U(&UU<W0@96YT97(@-#(@:68*("`@("`@("`@%
  414. XM('EO=2!A<F4@<W5R92!T;R!D;R!I="X@(`H@("`@("`@("`@069T97(@9F]RX
  415. XM;6%T=&EN9R!H87,@8V]M<&QE=&5D+"!Y;W4@(&UU<W0@(')E;6]V92`@=&AEN
  416. XM("!D:7-K"B`@("`@("`@("!F<F]M("!T:&4@(&1R:79E+"`@:6X@(&]R9&5RC
  417. XM('1O(&QE="!A;&P@:6YV;VQV960@9FEL97-Y<W1E;7,*("`@("`@("`@(&MN#
  418. XM;W<@=&AA="!T:&4@9&ES:R!J=7-T(&1I960@86YD(')E:6YC87)N871E9"X@P
  419. XM(`H*("`@("`@("`@()LS;41I<VM#;W!Y()LP;6-A;B!B92!U<V5D('1O(&-O,
  420. XM<'D@;65S<WED;W,@(&1I<VMS+"`@<')O=FED960@('EO=0H@("`@("`@("`@.
  421. XM:&%V92!O;F4@(&]R(&UO<F4@9FEL92!S>7-T96US(&UO=6YT960N("!.;W1E2
  422. XM+"!H;W=E=F5R+"!T:&%T"B`@("`@("`@("!$:7-K0V]P>2!L;V]K<R!A="!T*
  423. XM:&4@9&ES:R!S:7IE(&EN9F]R;6%T:6]N(&%S(&ET(&ES('!R97-E;G0*("`@Q
  424. XM("`@("`@(&EN('1H92!-;W5N=&QI<W0N("!4:&5R969O<F4@($1I<VM#;W!Y_
  425. XM("!W:6QL("!N;W0@(&-O<'D@('1H90H@("`@("`@("`@96YT:7)E(&1I<VL@!
  426. XM:68@:70@:7,@,3`M<V5C=&]R('=H:6QE('1H92!-;W5N=&QI<W0@8VQA:6USH
  427. XM(&ET"B`@("`@("`@("!I<R`@.2US96-T;W(N($EN('1H92!O<'!O<VET92!SE
  428. XM:71U871I;VXL(&ET('=I;&P@=')Y('1O(&-O<'D*("`@("`@("`@('1O;R!MT
  429. XM=6-H('=H:6-H('=I;&P@<F5S=6QT(&EN(')E860@97)R;W)S+"!W:&EC:"`@9
  430. XM;6%Y("!C875S90H@("`@("`@("`@=&AE(&QA<W0@('1R86-K(&YO="!T;R!B"
  431. XM92!C;W!I960N("!9;W4@8V%N(&-O;G-T<G5C="!S<&5C:6%L"B`@("`@("`@&
  432. XM("!-;W5N=&QI<W0@96YT<FEE<R!F;W(@."!O<B`Q,"!S96-T;W(@9&ES:W,@X
  433. XM:68@('EO=2`@<&QA;B`@=&\*("`@("`@("`@($1I<VM#;W!Y('1H96T[('1HO
  434. XM97)E(&ES(&YO(&YE960@=&\@<F5A;&QY(&UO=6YT('1H97-E+B`@"@H@("`@K
  435. XM()LQ;512041%34%22U,@"B`@("`@("`@("";,&U!;6EG82P@("`@($%M:6=AS
  436. XM1$]3+"`@("!7;W)K8F5N8V@@("`@87)E("`@('1R861E;6%R:W,@("`@;V8*Z
  437. XM("`@("`@("`@($-O;6UO9&]R92U!;6EG82P@26YC+B!-97-S>61O<R!I<R!P(
  438. XM<F5S=6UA8FQY(&$@=')A9&5M87)K("!O9@H@("`@("`@("`@365S<WE3;V9T\
  439. XM+"!);F,N("`*"B`@("`@FS%M05542$]2(`H@("`@("`@("`@FS!M5&AE("!M$
  440. XM97-S>2`@9FEL92!S>7-T96T@:&%N9&QE<B!I<R!W<FET=&5N(&)Y()LS;5-OH
  441. XM=7)C97)E<B";,&U/;&%F"B`@("`@("`@("";,VU2:&EA;'1O()LP;5-E:6)EJ
  442. XM<G0N("`*"@H*"@H*"@H*"@H*"B`@("`@2V]S;6]3;V9T("`@("`@("`@("`@E
  443. XM("`@("`@("`@("`@+38M("`@("`@("`@("`@("`@("`@("`@(%9E<G-I;VX@6
  444. X&,S0N-`H*=
  445. X``
  446. Xend
  447. Xsize 18456
  448. END_OF_FILE
  449. if test 25877 -ne `wc -c <'doc/msh.man.uu'`; then
  450.     echo shar: \"'doc/msh.man.uu'\" unpacked with wrong size!
  451. fi
  452. # end of 'doc/msh.man.uu'
  453. fi
  454. if test -f 'src/hanfile.c' -a "${1}" != "-c" ; then 
  455.   echo shar: Will not clobber existing file \"'src/hanfile.c'\"
  456. else
  457. echo shar: Extracting \"'src/hanfile.c'\" \(20226 characters\)
  458. sed "s/^X//" >'src/hanfile.c' <<'END_OF_FILE'
  459. X/*-
  460. X * $Id: hanfile.c,v 1.6 90/02/10 21:38:26 Rhialto Exp $
  461. X * $Log:    hanfile.c,v $
  462. X * Revision 1.6  90/02/10  21:38:26  Rhialto
  463. X * Optimized 12-bit fat unpacking.
  464. X * 
  465. X * Revision 1.5  90/01/27  20:26:51  Rhialto
  466. X * Fixed ATTR_ARCHIVED bit in MSWrite()
  467. X *
  468. X * Revision 1.4  90/01/23  02:32:23  Rhialto
  469. X * Add 16-bit FAT support.
  470. X *
  471. X * Revision 1.3  90/01/23  00:39:04  Rhialto
  472. X * Always return -1 on MSWrite error.
  473. X *
  474. X * Revision 1.2  89/12/17  23:04:39  Rhialto
  475. X * Add ATTR_READONLY support
  476. X *
  477. X * Revision 1.1  89/12/17  20:03:11  Rhialto
  478. X * Initial revision
  479. X *
  480. X * HANFILE.C
  481. X *
  482. X * The code for the messydos file system handler.
  483. X *
  484. X * This parts handles files and the File Allocation Table.
  485. X *
  486. X * This code is (C) Copyright 1989,1990 by Olaf Seibert. All rights reserved.
  487. X * May not be used or copied without a licence.
  488. X-*/
  489. X
  490. X#include "han.h"
  491. X#include "dos.h"
  492. X
  493. X#ifdef DEBUG
  494. X#   define    debug(x)  dbprintf x
  495. X#else
  496. X#   define    debug(x)
  497. X#endif
  498. X
  499. Xextern char    DotDot[1 + 8 + 3];
  500. X
  501. X/*
  502. X * Read the FAT from the disk, and count the free clusters.
  503. X */
  504. X
  505. Xint
  506. XGetFat()
  507. X{
  508. X    int         i;
  509. X    byte       *secptr;
  510. X
  511. X    if (!Fat && !(Fat = AllocMem((long) Disk.bps * Disk.spf, BufMemType))) {
  512. X    debug(("No memory for FAT\n"));
  513. X    return 0;
  514. X    }
  515. X    FatDirty = FALSE;
  516. X    for (i = 0; i < Disk.spf; i++) {
  517. X    if (secptr = GetSec(Disk.res + i)) {
  518. X        CopyMem(secptr, Fat + i * Disk.bps, (long) Disk.bps);
  519. X        FreeSec(secptr);
  520. X    } else {
  521. X        /* q&d way to set the entire FAT to FAT_EOF */
  522. X        setmem(Fat + i * Disk.bps, (int) Disk.bps, FAT_EOF);        /* 0xFF */
  523. X    }
  524. X    }
  525. X
  526. X    debug(("counting free clusters\n"));
  527. X
  528. X    Disk.nsectsfree = 0;
  529. X    for (i = MS_FIRSTCLUST; i <= Disk.maxclst; i++) {
  530. X    if (GetFatEntry((word) i) == FAT_UNUSED)
  531. X        Disk.nsectsfree += Disk.spc;
  532. X    }
  533. X
  534. X    return 1;
  535. X}
  536. X
  537. Xvoid
  538. XFreeFat()
  539. X{
  540. X    if (Fat) {
  541. X    FreeMem(Fat, (long) Disk.bps * Disk.spf);
  542. X    Fat = NULL;
  543. X    FatDirty = FALSE;
  544. X    }
  545. X}
  546. X
  547. X/*-
  548. X *  The FAT consists of 12-bits entries for each cluster,
  549. X *  indicating the next cluster in the chain, or FFF for EOF.
  550. X *
  551. X *  Every two entries are packed in three bytes, like this:
  552. X *
  553. X *  Two entries     abc  123 (for one cluster and the next)
  554. X *  are packed as    bc 3a 12
  555. X-*/
  556. X
  557. Xword
  558. XGetFatEntry(cluster)
  559. Xword        cluster;
  560. X{
  561. X    if (!Fat && !GetFat())
  562. X    return FAT_EOF;
  563. X
  564. X    if (Disk.fat16bits) {
  565. X    return OtherEndianWord(((word *)Fat)[cluster]);
  566. X    } else {
  567. X    register int    offset = 3 * (cluster / 2);
  568. X    register word    twoentries;
  569. X
  570. X    if (cluster & 1) {
  571. X        twoentries = Fat[offset + 1] >> 4;
  572. X        twoentries |= Fat[offset + 2] << 4;
  573. X    } else {
  574. X        twoentries = Fat[offset];
  575. X        twoentries |= (Fat[offset + 1] & 0x0F) << 8;
  576. X    }
  577. X
  578. X    /*
  579. X     * Convert the special values 0xFF0 .. 0xFFF to 16 bits so they
  580. X     * can be checked consistently.
  581. X     */
  582. X    if (twoentries >= 0xFF0)
  583. X        twoentries |= 0xF000;
  584. X
  585. X    return twoentries;
  586. X    }
  587. X}
  588. X
  589. X#ifndef READONLY
  590. X
  591. Xvoid
  592. XSetFatEntry(cluster, value)
  593. Xword        cluster;
  594. Xword        value;
  595. X{
  596. X    if (!Fat && !GetFat())
  597. X    return;
  598. X
  599. X    if (Disk.fat16bits) {
  600. X    ((word *)Fat)[cluster] = OtherEndianWord(value);
  601. X    } else {
  602. X    register int    offset = 3 * (cluster / 2);
  603. X
  604. X    if (cluster & 1) {          /* 123 kind of entry */
  605. X        Fat[offset + 2] = value >> 4;
  606. X        Fat[offset + 1] &= 0x0F;
  607. X        Fat[offset + 1] |= (value & 0x0F) << 4;
  608. X    } else {            /* abc kind of entry */
  609. X        Fat[offset + 0] = value;
  610. X        Fat[offset + 1] &= 0xF0;
  611. X        Fat[offset + 1] |= (value >> 8) & 0x0F;
  612. X    }
  613. X    }
  614. X
  615. X    FatDirty = TRUE;
  616. X}
  617. X
  618. X/*
  619. X * Find a free cluster to install as the one following this one. Start
  620. X * looking for it right after the given one, so we allocate the cluster
  621. X * chain as contiguous as possible. If we run off the end of the disk, we
  622. X * start again at the beginning. The termination test should not be
  623. X * necessary (and won't work if we are given MSFIRSTCLUST - 1) but won't
  624. X * harm either.
  625. X */
  626. X
  627. Xword
  628. XFindFreeCluster(prev)
  629. Xword        prev;
  630. X{
  631. X    register word   i;
  632. X
  633. X    if (prev == 0 || prev == FAT_EOF)
  634. X    prev = MS_FIRSTCLUST - 1;
  635. X
  636. X    if (Disk.nsectsfree >= Disk.spc) {
  637. X    for (i = prev + 1; i != prev; i++) {
  638. X        if (i > Disk.maxclst)       /* Wrap around */
  639. X        i = MS_FIRSTCLUST;
  640. X        if (GetFatEntry(i) == FAT_UNUSED) {
  641. X        SetFatEntry(i, FAT_EOF);
  642. X        if (prev >= MS_FIRSTCLUST)
  643. X            SetFatEntry(prev, i);
  644. X        Disk.nsectsfree -= Disk.spc;
  645. X        return i;
  646. X        }
  647. X    }
  648. X    }
  649. X    return FAT_EOF;
  650. X}
  651. X
  652. X/*
  653. X * Add a cluster to a cluster chain. For input, we get some cluster we
  654. X * know that is on the chain, even if it is the first one.
  655. X */
  656. X
  657. Xword
  658. XExtendClusterChain(cluster)
  659. Xregister word    cluster;
  660. X{
  661. X    register word   nextcluster;
  662. X
  663. X    /*
  664. X     * Find the end of the cluster chain to tack the new cluster on to.
  665. X     * Then FindFreeCluster will (or won't) extend the chain for us.
  666. X     */
  667. X    if (cluster != 0)
  668. X    while ((nextcluster = NextCluster(cluster)) != FAT_EOF) {
  669. X        cluster = nextcluster;
  670. X    }
  671. X
  672. X    return FindFreeCluster(cluster);
  673. X}
  674. X
  675. X/*
  676. X * Free a chain of clusters by setting their FAT entries to FAT_UNUSED.
  677. X */
  678. X
  679. Xvoid
  680. XFreeClusterChain(cluster)
  681. Xregister word    cluster;
  682. X{
  683. X    register word   nextcluster;
  684. X
  685. X    while (cluster != FAT_EOF) {
  686. X    nextcluster = NextCluster(cluster);
  687. X    SetFatEntry(cluster, FAT_UNUSED);
  688. X    Disk.nsectsfree += Disk.spc;
  689. X    cluster = nextcluster;
  690. X    }
  691. X}
  692. X
  693. X#endif                /* READONLY */
  694. X
  695. X/*
  696. X * This routine opens a file.
  697. X */
  698. X
  699. Xstruct MSFileHandle *
  700. XMSOpen(parentdir, name, mode)
  701. Xstruct MSFileLock *parentdir;
  702. Xchar           *name;
  703. Xlong        mode;
  704. X{
  705. X    struct MSFileLock *fl;
  706. X    struct MSFileHandle *fh = NULL;
  707. X    long        lockmode;
  708. X
  709. X    switch (mode) {
  710. X    case MODE_NEWFILE:
  711. X    case MODE_READWRITE:
  712. X    lockmode = EXCLUSIVE_LOCK ^ MODE_CREATEFILE;
  713. X    break;
  714. X    default:
  715. X    mode = MODE_OLDFILE;
  716. X    case MODE_OLDFILE:
  717. X    lockmode = SHARED_LOCK;
  718. X    }
  719. X
  720. X    if (fl = MSLock(parentdir, name, lockmode)) {
  721. Xmakefh:
  722. X    if (fl->msfl_Msd.msd_Attributes & ATTR_DIR) {
  723. X        error = ERROR_OBJECT_WRONG_TYPE;
  724. X        MSUnLock(fl);
  725. X    } else if (fh = AllocMem((long) sizeof (*fh), MEMF_PUBLIC)) {
  726. X#ifndef READONLY
  727. X        /* Do we need to truncate the file? */
  728. X        if (mode == MODE_NEWFILE && fl->msfl_Msd.msd_Cluster) {
  729. X        FreeClusterChain(fl->msfl_Msd.msd_Cluster);
  730. X        fl->msfl_Msd.msd_Cluster = 0;
  731. X        fl->msfl_Msd.msd_Filesize = 0;
  732. X        UpdateFileLock(fl);
  733. X        }
  734. X#endif
  735. X        fh->msfh_Cluster = fl->msfl_Msd.msd_Cluster;
  736. X        fh->msfh_SeekPos = 0;
  737. X        fh->msfh_FileLock = fl;
  738. X    } else {
  739. X        error = ERROR_NO_FREE_STORE;
  740. X        MSUnLock(fl);
  741. X    }
  742. X    return fh;
  743. X    }
  744. X#ifndef READONLY
  745. X    /*
  746. X     * If the file was not found, see if we can make a new one. Therefore
  747. X     * we need to have an empty spot in the desired directory, and create
  748. X     * an MSFileLock for it.
  749. X     */
  750. X
  751. X    if (!(lockmode & MODE_CREATEFILE) && (fl = EmptyFileLock)) {
  752. X    debug(("Creating new file\n"));
  753. X    EmptyFileLock = NULL;
  754. X    fl->msfl_Msd.msd_Attributes = ATTR_ARCHIVED;
  755. X    UpdateFileLock(fl);
  756. X
  757. X    goto makefh;
  758. X    }
  759. X    if (EmptyFileLock) {
  760. X    MSUnLock(EmptyFileLock);
  761. X    EmptyFileLock = NULL;
  762. X    }
  763. X#endif
  764. X
  765. X    return NULL;
  766. X}
  767. X
  768. Xvoid
  769. XMSClose(fh)
  770. Xregister struct MSFileHandle *fh;
  771. X{
  772. X    if (fh) {
  773. X    MSUnLock(fh->msfh_FileLock);
  774. X    FreeMem(fh, (long) sizeof (*fh));
  775. X    }
  776. X}
  777. X
  778. Xlong
  779. XMSSeek(fh, position, mode)
  780. Xstruct MSFileHandle *fh;
  781. Xlong        position;
  782. Xlong        mode;
  783. X{
  784. X    long        oldpos = fh->msfh_SeekPos;
  785. X    long        newpos = oldpos;
  786. X    long        filesize = fh->msfh_FileLock->msfl_Msd.msd_Filesize;
  787. X    word        cluster = fh->msfh_Cluster;
  788. X    word        oldcluster;
  789. X    word        newcluster;
  790. X
  791. X    switch (mode) {
  792. X    case OFFSET_BEGINNING:
  793. X    newpos = position;
  794. X    break;
  795. X    case OFFSET_CURRENT:
  796. X    newpos += position;
  797. X    break;
  798. X    case OFFSET_END:
  799. X    newpos = filesize - position;
  800. X    break;
  801. X    }
  802. X
  803. X    if (newpos < 0 || newpos > filesize) {
  804. X    error = ERROR_SEEK_ERROR;
  805. X    return -1;
  806. X    }
  807. X    newcluster = newpos / Disk.bpc;
  808. X    oldcluster = oldpos / Disk.bpc;
  809. X
  810. X    if (oldcluster > newcluster) {      /* Seek backwards */
  811. X    cluster = fh->msfh_FileLock->msfl_Msd.msd_Cluster;
  812. X    oldcluster = 0;
  813. X    }
  814. X    if (oldcluster < newcluster) {
  815. X    if (CheckLock(fh->msfh_FileLock))
  816. X        return -1L;
  817. X    while (oldcluster < newcluster) {
  818. X        cluster = NextCluster(cluster);
  819. X        oldcluster++;
  820. X    }
  821. X    }
  822. X    fh->msfh_Cluster = cluster;
  823. X    fh->msfh_SeekPos = newpos;
  824. X
  825. X    return oldpos;
  826. X}
  827. X
  828. Xlong
  829. XMSRead(fh, userbuffer, size)
  830. Xregister struct MSFileHandle *fh;
  831. Xregister byte  *userbuffer;
  832. Xregister long    size;
  833. X{
  834. X    long        oldsize;
  835. X
  836. X    if (CheckLock(fh->msfh_FileLock))
  837. X    return -1L;
  838. X
  839. X    if (fh->msfh_SeekPos + size > fh->msfh_FileLock->msfl_Msd.msd_Filesize)
  840. X    size = fh->msfh_FileLock->msfl_Msd.msd_Filesize - fh->msfh_SeekPos;
  841. X
  842. X    oldsize = size;
  843. X
  844. X    while (size > 0) {
  845. X    word        offset;
  846. X    word        sector;
  847. X    byte           *diskbuffer;
  848. X    long        insector;
  849. X    long        tocopy;
  850. X
  851. X    offset = fh->msfh_SeekPos % Disk.bpc;
  852. X    sector = ClusterOffsetToSector(fh->msfh_Cluster, (word) offset);
  853. X    if (diskbuffer = GetSec(sector)) {
  854. X        offset %= Disk.bps;
  855. X        insector = Disk.bps - offset;
  856. X        tocopy = lmin(size, insector);
  857. X
  858. X        CopyMem(diskbuffer + offset, userbuffer, tocopy);
  859. X        userbuffer += tocopy;
  860. X        size -= tocopy;
  861. X        FreeSec(diskbuffer);
  862. X        /* MSSeek(fh, tocopy, (long) OFFSET_CURRENT); */
  863. X        if ((fh->msfh_SeekPos += tocopy) % Disk.bpc == 0)
  864. X        fh->msfh_Cluster = NextCluster(fh->msfh_Cluster);
  865. X    } else {        /* Read error. Return amount successfully
  866. X                 * read, if any. Else return -1 for error. */
  867. X        if (size == oldsize) {
  868. X        return -1L;
  869. X        }
  870. X        return oldsize - size;
  871. X    }
  872. X    }
  873. X
  874. X    return oldsize;
  875. X}
  876. X
  877. Xlong
  878. XMSWrite(fh, userbuffer, size)
  879. Xregister struct MSFileHandle *fh;
  880. Xregister byte  *userbuffer;
  881. Xregister long    size;
  882. X{
  883. X#ifdef READONLY
  884. X    return -1;
  885. X#else
  886. X    long        oldsize;
  887. X    struct MSFileLock *fl = fh->msfh_FileLock;
  888. X    word        prevclust = fl->msfl_Msd.msd_Cluster;
  889. X    word        update = 0;
  890. X
  891. X    if (CheckLock(fl))
  892. X    return -1;
  893. X
  894. X    if (fl->msfl_Msd.msd_Attributes & ATTR_READONLY) {
  895. X    error = ERROR_WRITE_PROTECTED;
  896. X    return -1;
  897. X    }
  898. X
  899. X    oldsize = size;
  900. X
  901. X    while (size > 0) {
  902. X    /*
  903. X     * Do we need to extend the file?
  904. X     */
  905. X
  906. X    if (fh->msfh_Cluster == 0 || fh->msfh_Cluster == FAT_EOF) {
  907. X        word        newclust;
  908. X
  909. X        newclust = ExtendClusterChain(prevclust);
  910. X        debug(("Extend with %d\n", newclust));
  911. X        if (newclust != FAT_EOF) {
  912. X        if (prevclust == 0) {   /* Record first cluster in dir */
  913. X            fl->msfl_Msd.msd_Cluster = newclust;
  914. X        }
  915. X        fh->msfh_Cluster = newclust;
  916. X        prevclust = newclust;
  917. X        } else {
  918. X        error = ERROR_DISK_FULL;
  919. X        goto error;
  920. X        }
  921. X    }
  922. X    {
  923. X        word        offset;
  924. X        word        sector;
  925. X        byte       *diskbuffer;
  926. X        long        insector;
  927. X        long        tocopy;
  928. X
  929. X        offset = fh->msfh_SeekPos % Disk.bpc;
  930. X        sector = ClusterOffsetToSector(fh->msfh_Cluster, (word) offset);
  931. X        offset %= Disk.bps;
  932. X        insector = Disk.bps - offset;
  933. X        tocopy = lmin(size, insector);
  934. X
  935. X        if (tocopy == Disk.bps)
  936. X        diskbuffer = EmptySec(sector);
  937. X        else
  938. X        diskbuffer = GetSec(sector);
  939. X
  940. X        if (diskbuffer != NULL) {
  941. X        CopyMem(userbuffer, diskbuffer + offset, tocopy);
  942. X        userbuffer += tocopy;
  943. X        size -= tocopy;
  944. X        MarkSecDirty(diskbuffer);
  945. X        FreeSec(diskbuffer);
  946. X        /* MSSeek(fh, tocopy, (long) OFFSET_CURRENT); */
  947. X        if ((fh->msfh_SeekPos += tocopy) % Disk.bpc == 0)
  948. X            fh->msfh_Cluster = NextCluster(fh->msfh_Cluster);
  949. X        if (fh->msfh_SeekPos > fl->msfl_Msd.msd_Filesize)
  950. X            fl->msfl_Msd.msd_Filesize = fh->msfh_SeekPos;
  951. X        fl->msfl_Msd.msd_Attributes |= ATTR_ARCHIVED;
  952. X        update = 1;
  953. X        } else {        /* Write error. */
  954. X    error:
  955. X        if (update)
  956. X            UpdateFileLock(fl);
  957. X#if 1
  958. X        return -1;    /* We loose the information about how much
  959. X                 * data we wrote, but the standard file system
  960. X                 * seems to do it this way. */
  961. X#else
  962. X        if (size == oldsize) {
  963. X            return -1;
  964. X        }
  965. X        return oldsize - size;    /* Amount successfully written */
  966. X#endif
  967. X        }
  968. X    }
  969. X    }
  970. X
  971. X    if (update)
  972. X    UpdateFileLock(fl);
  973. X
  974. X    return oldsize;
  975. X#endif
  976. X}
  977. X
  978. Xlong
  979. XMSDeleteFile(parentdir, name)
  980. Xstruct MSFileLock *parentdir;
  981. Xbyte           *name;
  982. X{
  983. X#ifdef READONLY
  984. X    return DOSFALSE;
  985. X#else
  986. X    register struct MSFileLock *fl;
  987. X
  988. X    fl = MSLock(parentdir, name, EXCLUSIVE_LOCK);
  989. X    if (fl) {
  990. X    if (fl->msfl_Msd.msd_Attributes & ATTR_READONLY) {
  991. X        error = ERROR_DELETE_PROTECTED;
  992. X        goto error;
  993. X    }
  994. X    if (fl->msfl_Msd.msd_Attributes & ATTR_DIRECTORY) {
  995. X        struct FileInfoBlock fib;
  996. X
  997. X        /*
  998. X         * We normally can't get REAL exclusive locks on directories,
  999. X         * so we check here just to be sure. We don't want to delete
  1000. X         * anyone's current directory, do we?
  1001. X         */
  1002. X
  1003. X        if (fl->msfl_Refcount != 1 || fl == RootLock) {
  1004. X        error = ERROR_OBJECT_IN_USE;
  1005. X        goto error;
  1006. X        }
  1007. X        if (MSExamine(fl, &fib) &&  /* directory itself */
  1008. X        MSExNext(fl, &fib)) {   /* should fail */
  1009. X        if (error == 0) {
  1010. X        not_empty:
  1011. X            error = ERROR_DIRECTORY_NOT_EMPTY;
  1012. X        error:
  1013. X            MSUnLock(fl);
  1014. X            return DOSFALSE;
  1015. X        }
  1016. X        }
  1017. X        if (error != ERROR_NO_MORE_ENTRIES)
  1018. X        goto error;
  1019. X
  1020. X        error = 0;
  1021. X    }
  1022. X    if (fl->msfl_Msd.msd_Cluster)
  1023. X        FreeClusterChain(fl->msfl_Msd.msd_Cluster);
  1024. X    fl->msfl_Msd.msd_Name[0] = DIR_DELETED;
  1025. X    WriteFileLock(fl);
  1026. X    MSUnLock(fl);
  1027. X
  1028. X    return DOSTRUE;
  1029. X    }
  1030. X    return DOSFALSE;
  1031. X#endif
  1032. X}
  1033. X
  1034. Xlong
  1035. XMSSetDate(parentdir, name, datestamp)
  1036. Xstruct MSFileLock *parentdir;
  1037. Xbyte           *name;
  1038. Xstruct DateStamp *datestamp;
  1039. X{
  1040. X#ifdef READONLY
  1041. X    return DOSFALSE;
  1042. X#else
  1043. X    register struct MSFileLock *fl;
  1044. X
  1045. X    fl = MSLock(parentdir, name, EXCLUSIVE_LOCK);
  1046. X    if (fl) {
  1047. X    ToMSDate(&fl->msfl_Msd.msd_Date, &fl->msfl_Msd.msd_Time, datestamp);
  1048. X    WriteFileLock(fl);
  1049. X    MSUnLock(fl);
  1050. X
  1051. X    return DOSTRUE;
  1052. X    }
  1053. X    return DOSFALSE;
  1054. X#endif
  1055. X}
  1056. X
  1057. X/*
  1058. X * Create a new directory, with its own initial "." and ".." entries.
  1059. X */
  1060. X
  1061. Xstruct MSFileLock *
  1062. XMSCreateDir(parentdir, name)
  1063. Xstruct MSFileLock *parentdir;
  1064. Xbyte           *name;
  1065. X{
  1066. X#ifdef READONLY
  1067. X    return DOSFALSE;
  1068. X#else
  1069. X    register struct MSFileLock *fl;
  1070. X
  1071. X    /*
  1072. X     * Go create a new file. If we fail later, we have an empty file that
  1073. X     * we delete again.
  1074. X     */
  1075. X
  1076. X    fl = MSLock(parentdir, name, EXCLUSIVE_LOCK ^ MODE_CREATEFILE);
  1077. X    if (fl || error == ERROR_OBJECT_IN_USE) {
  1078. X    error = ERROR_OBJECT_EXISTS;
  1079. X    goto error;
  1080. X    }
  1081. X    if (error != 0) {
  1082. X    goto error;
  1083. X    }
  1084. X    if (fl = EmptyFileLock) {
  1085. X    debug(("Creating new dir\n"));
  1086. X    EmptyFileLock = NULL;
  1087. X    if ((fl->msfl_Msd.msd_Cluster = FindFreeCluster(FAT_EOF)) != FAT_EOF) {
  1088. X        struct MsDirEntry direntry;
  1089. X        byte       *sec;
  1090. X        word        sector;
  1091. X
  1092. X        sector = ClusterToSector(fl->msfl_Msd.msd_Cluster);
  1093. X        sec = EmptySec(sector);
  1094. X        if (sec == NULL)
  1095. X        goto error_no_free_store;
  1096. X        setmem(sec, (int) Disk.bps, 0);
  1097. X
  1098. X        /*
  1099. X         * Turn the file into a directory.
  1100. X         */
  1101. X        fl->msfl_Msd.msd_Attributes = ATTR_DIRECTORY;
  1102. X        UpdateFileLock(fl);
  1103. X
  1104. X        /*
  1105. X         * Create the "." entry.
  1106. X         */
  1107. X        direntry = fl->msfl_Msd;
  1108. X        strncpy(direntry.msd_Name, DotDot + 1, 8 + 3);
  1109. X        OtherEndianMsd(&direntry);
  1110. X        ((struct MsDirEntry *) sec)[0] = direntry;
  1111. X
  1112. X        /*
  1113. X         * Get the real parent directory because we will duplicate the
  1114. X         * directory entry in the subdirectory.
  1115. X         */
  1116. X
  1117. X        parentdir = MSParentDir(fl);
  1118. X        if (parentdir == NULL)      /* Cannot happen */
  1119. X        parentdir = MSDupLock(RootLock);
  1120. X
  1121. X        /*
  1122. X         * Create the ".." entry.
  1123. X         */
  1124. X        direntry = parentdir->msfl_Msd;
  1125. X        strncpy(direntry.msd_Name, DotDot, 8 + 3);
  1126. X        direntry.msd_Attributes = ATTR_DIRECTORY;
  1127. X        OtherEndianMsd(&direntry);
  1128. X        ((struct MsDirEntry *) sec)[1] = direntry;
  1129. X
  1130. X        MSUnLock(parentdir);
  1131. X
  1132. X        MarkSecDirty(sec);
  1133. X        FreeSec(sec);
  1134. X
  1135. X        /*
  1136. X         * Clear out the rest of the newly created directory.
  1137. X         */
  1138. X
  1139. X        while ((sector = NextClusteredSector(sector)) != SEC_EOF) {
  1140. X        sec = EmptySec(sector);
  1141. X        if (sec == NULL)
  1142. X            goto error_no_free_store;
  1143. X        setmem(sec, (int) Disk.bps, 0);
  1144. X        MarkSecDirty(sec);
  1145. X        FreeSec(sec);
  1146. X        }
  1147. X    } else {
  1148. X        MSUnLock(fl);
  1149. X        fl = NULL;
  1150. X        MSDeleteFile(parentdir, name);
  1151. X        error = ERROR_DISK_FULL;
  1152. X    }
  1153. X    }
  1154. X    if (EmptyFileLock) {
  1155. X    MSUnLock(EmptyFileLock);
  1156. X    EmptyFileLock = NULL;
  1157. X    }
  1158. X    return fl;
  1159. X
  1160. Xerror_no_free_store:
  1161. X    error = ERROR_NO_FREE_STORE;
  1162. Xerror:
  1163. X    if (fl)
  1164. X    MSUnLock(fl);
  1165. X    return DOSFALSE;
  1166. X#endif
  1167. X}
  1168. X
  1169. X/*
  1170. X * Rename a file or directory, possibly moving it to a different
  1171. X * directory.
  1172. X *
  1173. X * "Tuned" to also work in full directories by first deleting the source
  1174. X * name, then look for a slot to put the destination name. If that fails,
  1175. X * we undo the deletion. By playing with the cache, we even avoid a write
  1176. X * of the sector with the undeleted entry.
  1177. X */
  1178. X
  1179. Xlong
  1180. XMSRename(slock, sname, dlock, dname)
  1181. Xstruct MSFileLock *slock;
  1182. Xbyte           *sname;
  1183. Xstruct MSFileLock *dlock;
  1184. Xbyte           *dname;
  1185. X{
  1186. X#ifdef READONLY
  1187. X    return DOSFALSE;
  1188. X#else
  1189. X    struct MSFileLock *sfl;
  1190. X    struct MSFileLock *dfl;
  1191. X    long        success;
  1192. X    struct CacheSec *scache;
  1193. X    ulong        oldstatus;
  1194. X
  1195. X    success = DOSFALSE;
  1196. X    scache = NULL;
  1197. X    dfl = NULL;
  1198. X
  1199. X    sfl = MSLock(slock, sname, SHARED_LOCK);
  1200. X    if (sfl == NULL || sfl == RootLock)
  1201. X    goto error;
  1202. X
  1203. X    /*
  1204. X     * Now we are going to pull a dirty trick with the cache. We are going
  1205. X     * to temporarily delete the source file, in the chache only, and
  1206. X     * undelete it again if we cannot create the new name. And above all
  1207. X     * we want to avoid unnecessary writes if we decide not to do the
  1208. X     * deletion after all.
  1209. X     */
  1210. X    {
  1211. X    byte           *sec;
  1212. X    byte        old;
  1213. X
  1214. X    if ((sec = GetSec(sfl->msfl_DirSector)) == NULL)
  1215. X        goto error;
  1216. X    scache = FindSecByBuffer(sec);
  1217. X    oldstatus = scache->sec_Refcount;
  1218. X
  1219. X    old = sfl->msfl_Msd.msd_Name[0];
  1220. X    sfl->msfl_Msd.msd_Name[0] = DIR_DELETED;
  1221. X    WriteFileLock(sfl);
  1222. X    sfl->msfl_Msd.msd_Name[0] = old;
  1223. X
  1224. X    /*
  1225. X     * Don't FreeSec it yet; we don't want it written out to disk.
  1226. X     */
  1227. X    }
  1228. X
  1229. X    /*
  1230. X     * Now we have freed the directory entry of the source name, we might
  1231. X     * be able to use it for the destination name. But only if we also
  1232. X     * temporarily hide the MSFileLock on that spot. Gross hack ahead!
  1233. X     */
  1234. X
  1235. X    sfl->msfl_DirOffset = ~sfl->msfl_DirOffset;
  1236. X    dfl = MSLock(dlock, dname, EXCLUSIVE_LOCK ^ MODE_CREATEFILE);
  1237. X    sfl->msfl_DirOffset = ~sfl->msfl_DirOffset;
  1238. X
  1239. X    if (dfl != NULL || error == ERROR_OBJECT_IN_USE) {
  1240. X    error = ERROR_OBJECT_EXISTS;
  1241. X    goto undelete;
  1242. X    }
  1243. X    dfl = EmptyFileLock;
  1244. X    EmptyFileLock = NULL;
  1245. X    if (dfl == NULL) {
  1246. X    /*
  1247. X     * Sigh, we could not create the new name. But because of that, we
  1248. X     * are sure that we need to write nothing to the disk at all. So
  1249. X     * we can safely reset the sector-dirty flag to what it was
  1250. X     * before, if we also restore the cached sector.
  1251. X     */
  1252. Xundelete:
  1253. X    WriteFileLock(sfl);
  1254. X    scache->sec_Refcount = oldstatus;
  1255. X    goto error;
  1256. X    }
  1257. X    /*
  1258. X     * Now, if the moved entry was a directory, and it was moved to a
  1259. X     * different directory, we need to adapt its "..", which is the second
  1260. X     * entry.
  1261. X     */
  1262. X
  1263. X    if (sfl->msfl_Msd.msd_Attributes & ATTR_DIRECTORY &&
  1264. X    sfl->msfl_Parent != dfl->msfl_Parent) {
  1265. X    struct MSFileLock *parentdir;
  1266. X    struct MsDirEntry *dir;
  1267. X
  1268. X    if (dir = (struct MsDirEntry *)
  1269. X        GetSec(DirClusterToSector(sfl->msfl_Msd.msd_Cluster))) {
  1270. X        parentdir = MSParentDir(dfl);
  1271. X        /*
  1272. X         * Copy everything except the name which must remain "..". But
  1273. X         * first a quick consistency check...
  1274. X         */
  1275. X        debug(("Creating new \"..\"  "));
  1276. X        if (dir[1].msd_Name[1] == '.') {
  1277. X        CopyMem(&parentdir->msfl_Msd.msd_Attributes,
  1278. X            &dir[1].msd_Attributes,
  1279. X            (long) sizeof (struct MsDirEntry) -
  1280. X            OFFSETOF(MsDirEntry, msd_Attributes));
  1281. X        dir[1].msd_Attributes = ATTR_DIRECTORY;
  1282. X        OtherEndianMsd(&dir[1]);
  1283. X        MarkSecDirty(dir);
  1284. X        }
  1285. X#ifdef DEBUG
  1286. X        else
  1287. X        debug(("!!! No \"..\" found ??\n"));
  1288. X#endif
  1289. X        MSUnLock(parentdir);
  1290. X        FreeSec(dir);
  1291. X    }
  1292. X    }
  1293. X    /*
  1294. X     * Move the name from the new entry to the old filelock. We do this
  1295. X     * for the case that somebody else has a lock on the (possibly moved)
  1296. X     * file/directory. Also move the other administration.
  1297. X     */
  1298. X
  1299. X    strncpy(sfl->msfl_Msd.msd_Name, dfl->msfl_Msd.msd_Name, 8 + 3);
  1300. X    sfl->msfl_DirSector = dfl->msfl_DirSector;
  1301. X    sfl->msfl_DirOffset = dfl->msfl_DirOffset;
  1302. X    /*
  1303. X     * Free the old, and get the new parent directory. They might be the
  1304. X     * same, of course...
  1305. X     */
  1306. X    MSUnLock(sfl->msfl_Parent);
  1307. X    sfl->msfl_Parent = dfl->msfl_Parent;
  1308. X    dfl->msfl_Parent = NULL;
  1309. X    sfl->msfl_Msd.msd_Attributes &= ~ATTR_ARCHIVED;
  1310. X    WriteFileLock(sfl);         /* Write the new name; the old name
  1311. X                 * already has been deleted. */
  1312. X    success = DOSTRUE;
  1313. X
  1314. Xerror:
  1315. X    if (sfl)
  1316. X    MSUnLock(sfl);
  1317. X    if (dfl)
  1318. X    MSUnLock(dfl);
  1319. X    if (scache)
  1320. X    FreeSec(scache->sec_Data);
  1321. X
  1322. X    return success;
  1323. X#endif
  1324. X}
  1325. END_OF_FILE
  1326. if test 20226 -ne `wc -c <'src/hanfile.c'`; then
  1327.     echo shar: \"'src/hanfile.c'\" unpacked with wrong size!
  1328. fi
  1329. # end of 'src/hanfile.c'
  1330. fi
  1331. echo shar: End of archive 4 \(of 6\).
  1332. cp /dev/null ark4isdone
  1333. MISSING=""
  1334. for I in 1 2 3 4 5 6 ; do
  1335.     if test ! -f ark${I}isdone ; then
  1336.     MISSING="${MISSING} ${I}"
  1337.     fi
  1338. done
  1339. if test "${MISSING}" = "" ; then
  1340.     echo You have unpacked all 6 archives.
  1341.     rm -f ark[1-9]isdone
  1342. else
  1343.     echo You still need to unpack the following archives:
  1344.     echo "        " ${MISSING}
  1345. fi
  1346. ##  End of shell archive.
  1347. exit 0
  1348. -- 
  1349. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  1350. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  1351. Post requests for sources, and general discussion to comp.sys.amiga.
  1352.